package com.dinphin.site.novel.service.serviceImpl;

import com.alipay.api.AlipayApiException;
import com.alipay.api.AlipayClient;
import com.alipay.api.DefaultAlipayClient;
import com.alipay.api.internal.util.AlipaySignature;
import com.alipay.api.request.AlipayTradePagePayRequest;
import com.dinphin.site.novel.entity.Book;
import com.dinphin.site.novel.entity.Consume;
import com.dinphin.site.novel.entity.Login;
import com.dinphin.site.novel.entity.User;
import com.dinphin.site.novel.repository.*;
import com.dinphin.site.novel.service.UserService;
import com.dinphin.site.novel.config.AlipayConfig;
import com.dinphin.site.novel.util.IoUtil;
import com.dinphin.site.novel.util.Result;
import com.dinphin.site.novel.util.ResultCode;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.domain.Page;
import org.springframework.data.domain.PageRequest;
import org.springframework.data.domain.Pageable;
import org.springframework.stereotype.Service;
import org.springframework.ui.Model;
import org.springframework.web.multipart.MultipartFile;
import org.springframework.web.servlet.ModelAndView;

import javax.mail.Message;
import javax.mail.MessagingException;
import javax.mail.Session;
import javax.mail.Transport;
import javax.mail.internet.InternetAddress;
import javax.mail.internet.MimeMessage;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpSession;
import java.io.IOException;
import java.io.PrintWriter;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.*;

/**
 * Desc:
 * <p>
 * <p>
 * Created by dd on 2018/9/5 16:35
 */

@Service
public class UserServiceImpl implements UserService {
    @Autowired
    private LoginRepository loginRepository;
    @Autowired
    private ConsumeRepository consumeRepository;
    @Autowired
    private BookRepository bookRepository;
    @Autowired
    private BookListRepository bookListRepository;
    @Autowired
    private UserRepository userRepository;
    @Autowired
    private TypeRepository typeRepository;

    @Override
    public MimeMessage createSimpleMail(Session session, String code, String email) throws MessagingException {
        MimeMessage message = new MimeMessage(session);
        //指明邮件的发件人
        message.setFrom(new InternetAddress("wky1813721@126.com"));

        message.setRecipient(Message.RecipientType.TO, new InternetAddress(email));
        //邮件的标题
        message.setSubject("墨阅小说网");
        //邮件的文本内容
        message.setContent("尊敬的用户,欢迎你使用墨阅小说网，我们期待您的加入。 本次注册验证码为:" + code +" 请在30分钟内提交验证码完成本次操作，切勿将验证码泄露于他人。","text/html;charset=UTF-8");
        //返回创建好的邮件对象
        return message;
    }

    @Override
    public String generateShortUuid() {
        Random random = new Random();
        String result = "";
        for (int i = 0; i < 6; i++) {
            result += random.nextInt(10);
        }
        return result;
    }


    @Override
    public boolean updateUser(User user) {
        userRepository.save(user);
        User user1 = userRepository.findById(user.getUserId()).get();
        if (user1.equals(user)) return true;
        else return false;
    }

    @Override
    public void payment(HttpServletRequest request, HttpServletResponse response) throws IOException, AlipayApiException {
        PrintWriter out = response.getWriter();
        AlipayClient alipayClient = new DefaultAlipayClient(AlipayConfig.gatewayUrl, AlipayConfig.app_id, AlipayConfig.merchant_private_key, "json", AlipayConfig.charset, AlipayConfig.alipay_public_key, AlipayConfig.sign_type);
        //设置请求参数
        AlipayTradePagePayRequest alipayRequest = new AlipayTradePagePayRequest();
        alipayRequest.setReturnUrl(AlipayConfig.return_url);
        alipayRequest.setNotifyUrl(AlipayConfig.notify_url);
        SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd-HH-mm-ss");
        String data = sdf.format(new Date());
        String out_trade_no = data.replace("-", "");
        //商户订单号，商户网站订单系统中唯一订单号，必填
        String total_amount = request.getParameter("WIDtotal_amount");
        //订单名称，必填
        String subject = request.getParameter("WIDsubject");
        //商品描述，可空
        String body = new String(request.getParameter("WIDbody").getBytes("ISO-8859-1"), "UTF-8");
        alipayRequest.setBizContent("{\"out_trade_no\":\"" + out_trade_no + "\","
                + "\"total_amount\":\"" + total_amount + "\","
                + "\"subject\":\"" + subject + "\","
                + "\"body\":\"" + body + "\","
                + "\"timeout_express\":\"10m\","
                + "\"product_code\":\"FAST_INSTANT_TRADE_PAY\"}");

        //若想给BizContent增加其他可选请求参数，以增加自定义超时时间参数timeout_express来举例说明
        //alipayRequest.setBizContent("{\"out_trade_no\":\""+ out_trade_no +"\","
        //		+ "\"total_amount\":\""+ total_amount +"\","
        //		+ "\"subject\":\""+ subject +"\","
        //		+ "\"body\":\""+ body +"\","
        //		+ "\"timeout_express\":\"10m\","
        //		+ "\"product_code\":\"FAST_INSTANT_TRADE_PAY\"}");
        //请求参数可查阅【电脑网站支付的API文档-alipay.trade.page.pay-请求参数】章节

        //请求
        String result = alipayClient.pageExecute(alipayRequest).getBody();
        //输出
        out.println(result);
        System.out.println("asdfas" + result);
    }

    @Override
    public void returnUrl(HttpServletRequest request, HttpServletResponse response, HttpSession session) throws AlipayApiException, IOException, ParseException {
        PrintWriter out = response.getWriter();
        Map<String, String> params = new HashMap<String, String>();
        Map<String, String[]> requestParams = request.getParameterMap();
        for (Iterator<String> iter = requestParams.keySet().iterator(); iter.hasNext(); ) {
            String name = (String) iter.next();
            String[] values = (String[]) requestParams.get(name);
            String valueStr = "";
            for (int i = 0; i < values.length; i++) {
                valueStr = (i == values.length - 1) ? valueStr + values[i]
                        : valueStr + values[i] + ",";
            }
            //乱码解决，这段代码在出现乱码时使用
            // valueStr = new String(valueStr.getBytes("ISO-8859-1"), "utf-8");
            params.put(name, valueStr);
        }

        boolean signVerified = AlipaySignature.rsaCheckV1(params, AlipayConfig.alipay_public_key, AlipayConfig.charset, AlipayConfig.sign_type); //调用SDK验证签名

        //——请在这里编写您的程序（以下代码仅作参考）——
        if (signVerified) {
            //商户订单号
            String out_trade_no = new String(request.getParameter("out_trade_no").getBytes("ISO-8859-1"), "UTF-8");

            //支付宝交易号
            String trade_no = new String(request.getParameter("trade_no").getBytes("ISO-8859-1"), "UTF-8");

            //付款金额
            String total_amount = new String(request.getParameter("total_amount").getBytes("ISO-8859-1"), "UTF-8");

            String time = new String(request.getParameter("timestamp").getBytes("ISO-8859-1"), "UTF-8");
            String consumeType = "充值";
            User sessionUser = (User) session.getAttribute("user");
            User user = userRepository.findById(sessionUser.getUserId()).get();

            List<Consume> consumeList = consumeRepository.findByConsumeTypeAndUserId("充值", user.getUserId());
            Long consumeMoney = (long) 0;
            for (Consume consume1 : consumeList
                    ) {
                consumeMoney += consume1.getConsumeMoney();
            }
            Consume consume = new Consume();
            Date date = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss").parse(time);
            long beforeMoney = 0;
            if (user.getUserRewards() == null) {
                beforeMoney = 0;
            } else {
                beforeMoney = user.getUserRewards();
            }
            consume.setConsumeDate(date);
            consume.setUserId(user.getUserId());
            consume.setConsumeType(consumeType);
            consume.setIsShow(1);
            float money = Float.parseFloat(total_amount);
            consume.setConsumeMoney((long) money);
            long virtualMoney = (long) money * 100;
            user.setUserRewards(virtualMoney + beforeMoney);
            Long totalMoney = consumeMoney + (long) money;
            System.out.println("totaly" + totalMoney);
            System.out.println("consume" + consumeMoney);
            if (totalMoney >= 800 && totalMoney < 1600) {
                user.setRoleId("2");
            }
            if (totalMoney >= 1600) {
                user.setRoleId("3");
            }
            consumeRepository.save(consume);
            userRepository.save(user);
        } else {
            out.println("验签失败");
        }
    }

    @Override
    public void buyBook(Long bookId, Long userId) {
        User user = userRepository.findById(userId).get();
        Long userMoney = user.getUserRewards();
        Book book = bookRepository.findById(bookId).get();
        int bookMoney = book.getBookRewards();
        Long afterUserMoney = userMoney - bookMoney;
        Consume consume = new Consume();
        consume.setUserId(userId);
        consume.setConsumeMoney(bookMoney);
        consume.setConsumeObjectId(bookId);
        Date date = new Date();
        consume.setConsumeDate(date);
        consume.setConsumeNote("*");
        consume.setIsShow(1);
        consume.setConsumeType("消费");
        user.setUserRewards(afterUserMoney);
        userRepository.save(user);
        consumeRepository.save(consume);
    }


    @Override
    public void sendEmail(String email, String code) throws MessagingException {
        Properties prop = new Properties();
        prop.setProperty("mail.host", "smtp.126.com");
        prop.setProperty("mail.transport.protocol", "smtp");
        prop.setProperty("mail.smtp.auth", "true");
        //使用JavaMail发送邮件的5个步骤
        //1、创建session
        Session session = Session.getInstance(prop);
        //开启Session的debug模式，这样就可以查看到程序发送Email的运行状态
        session.setDebug(true);
        //2、通过session得到transport对象
        Transport ts = session.getTransport();
        //3、使用邮箱的用户名和密码连上邮件服务器，发送邮件时，发件人需要提交邮箱的用户名和密码给smtp服务器，用户名和密码都通过验证之后才能够正常发送邮件给收件人。
        ts.connect("smtp.126.com", "wky1813721", "wky199808");
        //4、创建邮件
        Message message = createSimpleMail(session, code, email);
        //5、发送邮件
        ts.sendMessage(message, message.getAllRecipients());
        ts.close();
    }
    public void register(String email, String phone, String password, String userAcount, String thirday) {
        SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd-HH-mm-ss");
        String data = sdf.format(new Date());
        String userName = "moyue" + data.replace("-", "");
        User user = new User();
        user.setUserName(userName);
        user.setRoleId("1");
        user.setUserRewards((long) 0);
        User user1 = userRepository.save(user);
        Login login = new Login();
        Login login1 = new Login();
        Login login2 = new Login();
        login.setIdentity(userAcount);
        login.setLoginType("account");
        login1.setIdentity(email);
        login1.setLoginType("email");
        login2.setLoginType("phone");
        login2.setIdentity(phone);
        login1.setCertificate(password);
        login2.setCertificate(password);
        login.setCertificate(password);
        login1.setUserId(user1.getUserId());
        login.setUserId(user1.getUserId());
        login2.setUserId(user1.getUserId());
        loginRepository.save(login);
        loginRepository.save(login1);
        loginRepository.save(login2);
        if (thirday != null && !thirday.equals("")) {
            Login login3 = new Login();
            login3.setLoginType("GitHub");
            login3.setIdentity(thirday);
            login3.setCertificate(password);
            login3.setUserId(user1.getUserId());
            loginRepository.save(login3);
        }
    }
    @Override
    public  boolean judgeIdentity (String identity){
        Login login = loginRepository.findByIdentity(identity);
        if (login != null) {
            return true;
        } else {
            return false;
        }
    }

    @Override
    public ModelAndView uploaadUserImg(MultipartFile file, HttpSession session) {
        User user = (User) session.getAttribute("user");
        IoUtil ioUtil = new IoUtil();
        if (user.getUserHeadPortraitUrl()!=null)ioUtil.deleteFile(user.getUserHeadPortraitUrl());
        String url = "/upload/user/" + user.getUserId() + "/img/" + file.getOriginalFilename();
        ioUtil.saveFile(file, url);
        user.setUserHeadPortraitUrl(url);
        userRepository.save(user);
        return new ModelAndView("redirect:/user/myhomehtml");

    }

    @Override
    public Result updateUser(User userUpdate, String usersBirthday, HttpSession session) {
        usersBirthday = usersBirthday.replace("Z", " UTC");//注意是空格+UTC
        SimpleDateFormat format = new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss.SSSZ");//注意格式化的表达式
        try {
            Date date = format.parse(usersBirthday);
            User user = (User) session.getAttribute("user");
            user.setUserName(userUpdate.getUserName());
            user.setUserSex(userUpdate.getUserSex());
            user.setUserBirthday(date);
            user.setDescription(userUpdate.getDescription());
            userRepository.save(user);
            return new Result(ResultCode.SUCCESS);
        } catch (ParseException e) {
            e.printStackTrace();
            return new Result(ResultCode.FAIL);
        }
    }

    @Override
    public Result userMessage(HttpSession session) {
        User userSession = (User) session.getAttribute("user");
        User user = userRepository.findById(userSession.getUserId()).get();
        return new Result(ResultCode.SUCCESS, user);
    }
    @Override
    public void tobms(Model model, String currentPage){
        int pram ;
        if ((currentPage == null) ){
            pram=1;
        }else {
            pram=Integer.parseInt(currentPage);
        }
        Pageable pageable = new PageRequest(pram-1, 10);
        Page<User> page = userRepository.findAll(pageable);
        model.addAttribute("totalPages", page.getTotalPages());
        model.addAttribute("userlist", page.getContent());
        model.addAttribute("page",pram);
    }
    @Override
    public User searchUser(String userName){
        return userRepository.findByUserName(userName);
    }
    @Override

    public void delateUsers( Long[] usersId){
        for (int i = 0; i < usersId.length; i++) {
            userRepository.deleteById(usersId[i]);
            loginRepository.deleteByUserId(usersId[i]);
        }
    }
    @Override
    public void deleteUser(Long userId){
        userRepository.deleteById(userId);
        loginRepository.deleteByUserId(userId);
    }

    public void delateUsers( String[] usersId){
        Long Id = Long.valueOf(0);
        for (int i = 0; i < usersId.length; i++) {
            Id = Long.parseLong(usersId[i]);
            userRepository.deleteById(Id);
            loginRepository.deleteByUserId(Id);
        }
    }
}
